package com.dongdongshop.service.impl;

import com.dongdongshop.exception.NoGoods;
import com.dongdongshop.mapper.TbSeckillGoodsMapper;
import com.dongdongshop.mapper.TbSeckillOrderMapper;
import com.dongdongshop.pojo.TbSeckillGoods;
import com.dongdongshop.pojo.TbSeckillGoodsExample;
import com.dongdongshop.service.SecKillService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@com.alibaba.dubbo.config.annotation.Service
public class SecKillServiceImpl implements SecKillService {

    @Resource
    private TbSeckillGoodsMapper seckillGoodsMapper;

    @Resource
    private TbSeckillOrderMapper seckillOrderMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    //获取秒杀商品列表
    @Override
    public List<TbSeckillGoods> getGoodList() {
        //redis序列化 可以是String类型或Hash类型
        redisTemplate.setValueSerializer(new StringRedisSerializer());

        //查看缓存
        List<TbSeckillGoods> seckillGoods = (List<TbSeckillGoods>)redisTemplate.boundHashOps("seckillGoods").values();
        if(seckillGoods == null || seckillGoods.size() == 0){
            //获取秒杀商品列表
            TbSeckillGoodsExample tbSeckillGoodsExample = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = tbSeckillGoodsExample.createCriteria();
            criteria.andStatusEqualTo("1");
            criteria.andStockCountGreaterThan(0);

            Date date = new Date();
            //当前时间大于开始时间
            criteria.andStartTimeLessThanOrEqualTo(date);
            //当前时间小于等于结束时间
            criteria.andEndTimeGreaterThanOrEqualTo(date);
            seckillGoods = seckillGoodsMapper.selectByExample(tbSeckillGoodsExample);
            for (TbSeckillGoods seckillGood : seckillGoods) {
                redisTemplate.boundHashOps("seckillGoods").put(seckillGood.getId(), seckillGood);
                //将预减库存单独存入redis
                redisTemplate.boundValueOps(seckillGood.getId()).set(seckillGood.getStockCount().toString());
            }
        }
        return seckillGoods;
    }

    //根据Id获取秒杀商品详情
    @Override
    public TbSeckillGoods findSeckillById(Long id) {
        TbSeckillGoods seckillGoods = seckillGoodsMapper.selectByPrimaryKey(id);
        return seckillGoods;
    }

    //生成订单
    @Override
    public void createOrder(Long id, String username) throws Exception {
        //限制用户抢购单件商品
//        Object user_seckillGood = redisTemplate.boundHashOps("user_seckillGood").get(username + id);
//        if(user_seckillGood != null){
//            throw new Exception("已抢购过该商品");
//        }

        String stockCount = (String) redisTemplate.boundValueOps(id).get();
        if(stockCount == null || Long.parseLong(stockCount) <= 0){
            throw new NoGoods();
        }
        //从缓存中根据Id查询

//        if(seckillGoods == null || seckillGoods.getStockCount() <= 0){
//            throw new Exception("商品卖光了");
//        }
        //减库存
//        seckillGoods.setStockCount(seckillGoods.getStockCount() -1);
        Long decrement = redisTemplate.boundValueOps(id).decrement();
        //更新缓存
        if(decrement <= 0){  //如果是最后一件, 清空缓存, 修改数据库
            TbSeckillGoods seckillGoods = (TbSeckillGoods)redisTemplate.boundHashOps("seckillGoods").get(id);
            seckillGoods.setStockCount(0);
            seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
            redisTemplate.boundHashOps("seckillGoods").delete(id);
        }else{
            redisTemplate.boundValueOps(id).set(decrement.toString());
        }

        //限制用户抢购单件商品
//        redisTemplate.boundHashOps("user_seckillGood").put(username + id, 1);

        //mq消息发送
        String message = username + "," + id;
        rocketMQTemplate.convertAndSend("seckill-goods", message);
    }
}
